/**
 * 用来提供一些sort测试中的辅助函数；
 * @author: sundx
 * @date: 2020-05-29 15:02:03
 * @Last Modified by: sundx
 * @Last Modified time: 2020-05-29 19:13:07
 */
#ifndef __SORTTESTHELPER_H__
#define __SORTTESTHELPER_H__

#include <algorithm>
#include <cassert>
#include <ctime>
#include <iostream>
#include <string>

namespace SortTestHelper {

// 生成n个[left,right]闭区间内的int型整数
int *generateRandomArray(int n, int left, int right) {
  assert(left <= right);
  int *arr = new int[n];
  srand(time(NULL));
  for (int i = 0; i < n; ++i) {
    arr[i] = rand() % (right - left + 1) + left;
  }
  return arr;
}

int *copyIntArray(int a[], int n) { //复制一个数组；
  int *arr = new int[n];
  std::copy(a, a + n, arr);
  return arr;
}

// 生成n个元素的数组，交换swaptimes次；
int *generateNearlySortedArray(int n, int swaptimes) {
  int *arr = new int[n];
  for (int i = 0; i < n; ++i) {
    arr[i] = i;
  }
  srand(time(NULL));
  for (int i = 0; i < swaptimes; ++i) {
    int k = rand() % n;
    int j = rand() % n;
    std::swap(arr[k], arr[j]);
  }
  return arr;
}

// 生成n个元素的数组范围[l,r]，交换swaptimes次；
int *generateNearlySortedArray(int n, int l, int r, int swaptimes) {
  srand(time(NULL));
  int *arr = new int[n];
  for (int i = 0; i < n; ++i) {
    arr[i] = rand() % (r - l + 1) + l;
  }
  std::sort(arr, arr + n);
  for (int i = 0; i < swaptimes; ++i) {
    int k = rand() % n;
    int j = rand() % n;
    std::swap(arr[k], arr[j]);
  }
  return arr;
}

template <typename T> void printArray(T arr[], int n) { //打印数组中的每一项
  for (int i = 0; i < n; ++i) {
    std::cout << arr[i] << " ";
  }
  std::cout << std::endl;
}

template <typename T> bool isSorted(T arr[], int n) { //测试是否有序
  for (int i = 0; i < n - 1; ++i) {
    if (arr[i] > arr[i + 1]) {
      std::cout << "wrong : " << i << std::endl;
      return false;
    }
  }
  return true;
}

template <typename T>
void sortInfo(std::string sortName, void funcName(T *, int), T arr[], int n) {
  // 测试不同排序函数函数的性能；
  clock_t startTime = clock();
  funcName(arr, n);
  clock_t endTime = clock();
  assert(isSorted(arr, n));

  std::cout << sortName << " : " << double(endTime - startTime) / CLOCKS_PER_SEC
            << "s" << std::endl;
}

} // namespace SortTestHelper
#endif // __SORTTESTHELPER_H__